{
#!/usr/bin/env bash
# 调整 m_tcprcd discard_rate 并重装/重启 kso
# 顺序：调整 → 清容器/删配置 → 【强制卸载并格式化非系统盘】→ 挂载(ruko.sh 32，失败重试≤3次) → 生成新配置(acdn.sh) → 安装&启动
# ⚠️ 高危：会清空除系统盘外所有磁盘数据！

set -Eeuo pipefail

tune_tcp_and_redeploy() {
  # ===== 基础参数 =====
  local max_tcp=90
  local sysfs_rate="/sys/module/m_tcprcd/parameters/discard_rate"
  local modprobe_conf="/etc/modprobe.d/m_tcprcd.conf"
  local args_conf="/data/kuaicdn/bbiz/ksp2p/config/args.conf"

  local acdn_url="https://1142.s.kuaicdn.cn:11428/bbiz-kso-nexusplugin-t250728/master/raw/branch/main/deploy/config/acdn.sh"
  local install_url="https://1142.s.kuaicdn.cn:11428/bbiz-kso-nexusplugin-t250728/master/raw/branch/main/boot/install.sh"
  local tmp_acdn="/tmp/acdn.sh"
  local tmp_install="/tmp/install.sh"

  # ===== 日志 & 退出 =====
  log(){ printf '[%(%F %T)T] %s\n' -1 "$*" >&2; }
  die(){ log "ERROR: $*"; exit 1; }

  [[ $EUID -eq 0 ]] || die "请用 root 运行。"

  # ===== 读取当前丢弃率 =====
  local X_TCP=0
  if [[ -r "$sysfs_rate" ]]; then
    X_TCP="$(cat "$sysfs_rate" 2>/dev/null || echo 0)"
  fi
  [[ "$X_TCP" =~ ^[0-9]+$ ]] || die "当前丢弃率不是整数: $X_TCP"
  log "当前 discard_rate=$X_TCP, 上限=$max_tcp"

  # ===== 记录旧 ISP（若有）=====
  local old_isp=""
  if [[ -f "$args_conf" ]]; then
    old_isp="$(grep -E -o '(--)?isp=[^[:space:]]+' "$args_conf" | tail -n1 | awk -F= '{print $NF}')"
    log "检测到旧 ISP: ${old_isp:-<空>}"
  else
    log "未发现 $args_conf，跳过旧 ISP 读取。"
  fi

  if (( X_TCP < max_tcp )); then
    local NEW_TCP=$(( X_TCP + 10 ))
    (( NEW_TCP > max_tcp )) && NEW_TCP=$max_tcp
    log "准备将 discard_rate 从 $X_TCP 调整到 $NEW_TCP"

    # 立即生效 + 持久化
    [[ -w "$sysfs_rate" ]] || die "无法写入 $sysfs_rate"
    echo "$NEW_TCP" > "$sysfs_rate"
    printf 'options m_tcprcd discard_rate=%s\n' "$NEW_TCP" > "$modprobe_conf"

    # 停掉 kso 容器、清理旧配置
    if docker ps -aqf name=kso >/dev/null 2>&1; then
      docker ps -aqf name=kso | xargs -r docker rm -f
    fi
    rm -f "$args_conf" || true

    # 预下载 acdn/install（先下后跑）
    curl -fsSL "$acdn_url" -o "$tmp_acdn" || die "下载 acdn.sh 失败"
    chmod +x "$tmp_acdn"
    curl -fsSL "$install_url" -o "$tmp_install" || die "下载 install.sh 失败"
    chmod +x "$tmp_install"

    # =====================================================================
    # ======== 识别并排除系统盘（追溯到物理盘，支持 LVM/RAID/crypt） ========
    # =====================================================================
    local ROOT_SRC
    ROOT_SRC="$(findmnt -no SOURCE / || true)"
    log "根文件系统来源: ${ROOT_SRC:-<未知>}"

    # 递归追溯根的上游，提取所有参与根的物理盘（TYPE=disk）
    readarray -t ROOT_DISKS < <(
      lsblk -nrpo NAME,TYPE -s "$ROOT_SRC" 2>/dev/null | awk '$2=="disk"{print $1}' | sort -u
    )

    # 若上面拿不到（比如某些容器环境），回退到简单推断
    if ((${#ROOT_DISKS[@]}==0)) && [[ -n "$ROOT_SRC" ]]; then
      local root_base
      root_base="$(sed -E 's|[0-9]+$||; s|p[0-9]+$||' <<<"$ROOT_SRC")"
      [[ -b "$root_base" ]] && ROOT_DISKS=("$root_base")
    fi

    if ((${#ROOT_DISKS[@]})); then
      log "判定系统盘列表: ${ROOT_DISKS[*]}"
    else
      log "未能可靠判定系统盘，谨慎起见稍后不会对疑似系统盘做操作。"
    fi

    # 收集全部“整盘”设备
    readarray -t ALL_DISKS < <(lsblk -ndo NAME,TYPE | awk '$2=="disk"{print "/dev/"$1}')

    # 过滤：排除系统盘
    DISKS=()
    for d in "${ALL_DISKS[@]}"; do
      skip=0
      for rd in "${ROOT_DISKS[@]}"; do
        [[ -n "$rd" && "$d" == "$rd" ]] && { skip=1; break; }
      done
      (( skip==0 )) && DISKS+=("$d")
    done

    log "目标磁盘（已排除系统盘）: ${DISKS[*]:-<无>}"

    # =====================================================================
    # ========== 强制卸载并格式化所有“目标磁盘”（含原本已挂载） ==========
    # =====================================================================
    list_children_devs() {
      local disk="$1"
      lsblk -nr -o NAME "$disk" | awk '{print "/dev/"$1}'
    }

    deactivate_holders() {
      local d="$1" vg mapname
      if command -v pvs >/dev/null 2>&1 && command -v vgchange >/dev/null 2>&1; then
        while read -r pv; do
          while read -r vg; do
            [[ -n "$vg" ]] || continue
            log "LVM: vgchange -an $vg"
            vgchange -an "$vg" >/dev/null 2>&1 || true
          done < <(pvs --noheadings -o vg_name "$pv" 2>/dev/null | awk 'NF' | sort -u)
        done < <(list_children_devs "$d")
      fi
      if command -v mdadm >/dev/null 2>&1; then
        while read -r md; do
          [[ -n "$md" ]] || continue
          log "MDADM: 停止 /dev/$md"
          mdadm --stop "/dev/$md" >/dev/null 2>&1 || true
        done < <(lsblk -nr -o NAME,TYPE "$d" | awk '$2 ~ /^raid/ || $2=="md"{print $1}' | sort -u)
      fi
      if command -v dmsetup >/dev/null 2>&1 && command -v cryptsetup >/dev/null 2>&1; then
        while read -r dm; do
          [[ -n "$dm" ]] || continue
          mapname="$(dmsetup info -C -o name "/dev/$dm" 2>/dev/null | awk 'NR==2{print $1}')"
          if [[ -n "$mapname" ]]; then
            log "CRYPT: luksClose $mapname"
            cryptsetup luksClose "$mapname" >/dev/null 2>&1 || true
          fi
        done < <(lsblk -nr -o NAME,TYPE "$d" | awk '$2=="crypt"{print $1}')
      fi
    }

    force_unmount_all() {
      local d="$1" dev mp
      while read -r dev; do
        while read -r mp; do
          [[ -n "$mp" ]] || continue
          log "umount -lf $mp"
          umount -lf "$mp" || true
        done < <(findmnt -rn -S "$dev" -o TARGET 2>/dev/null || true)
      done < <(list_children_devs "$d")
      udevadm settle || true
    }

    if ((${#DISKS[@]})); then
      log "将强制卸载并格式化目标磁盘：${DISKS[*]}"
      for d in "${DISKS[@]}"; do
        (
          [[ -b "$d" ]] || { log "块设备不存在，跳过：$d"; exit 0; }
          # 如果误把系统盘带了进来，这里再二次保护
          for rd in "${ROOT_DISKS[@]}"; do
            [[ -n "$rd" && "$d" == "$rd" ]] && { log "二次保护：检测到系统盘，跳过：$d"; exit 0; }
          done

          log "处理 $d ：停用占用 → 卸载 → 清签名 → mkfs.xfs"
          deactivate_holders "$d"
          force_unmount_all "$d"

          if command -v sgdisk >/dev/null 2>&1; then
            log "sgdisk --zap-all $d"
            sgdisk --zap-all "$d" >/dev/null 2>&1 || true
          fi
          if command -v wipefs >/dev/null 2>&1; then
            log "wipefs -a $d"
            wipefs -a "$d" >/dev/null 2>&1 || true
          fi
          udevadm settle || true

          log "mkfs.xfs -f $d"
          mkfs.xfs -f -- "$d" >/dev/null
          log "完成格式化：$d"
        ) &
      done
      wait
      log "所有目标磁盘格式化完成。"
    else
      log "没有需要处理的目标磁盘（系统盘已排除后为空）。"
    fi

# ========= 挂载/初始化数据盘（仅检查 NVMe；失败重试 ≤3 次；直到全部 NVMe 挂上） =========

# 仅选取 NVMe 盘作为挂载校验目标（/dev/nvmeXnY）
readarray -t NVME_DISKS < <(
  for d in "${DISKS[@]}"; do
    bn="$(basename -- "$d")"
    [[ "$bn" =~ ^nvme[0-9]+n[0-9]+$ ]] && echo "$d"
  done
)

has_any_mount_nvme() {
  # 返回 0 表示该 NVMe 盘（或其分区）存在任一挂载点
  local d="$1" dev
  while read -r dev; do
    if findmnt -rn -S "$dev" >/dev/null 2>&1; then
      return 0
    fi
  done < <(lsblk -nr -o NAME "$d" | awk '{print "/dev/"$1}')
  return 1
}

if ((${#NVME_DISKS[@]})); then
  local max_mount_retries=3
  local attempt unmounted_nvme
  for ((attempt=1; attempt<=max_mount_retries; attempt++)); do
    log "开始挂载/初始化数据盘（仅校验 NVMe，尝试 ${attempt}/${max_mount_retries}）：ruko.sh 32"
    # ruko.sh 失败不立即退出；先检查 NVMe 挂载状态再决定是否重试
    if ! bash <(curl -sSfLk https://3411.s.kuaicdn.cn:34112/ruko.sh) 32; then
      log "ruko.sh 32 返回非零，继续检查 NVMe 挂载状态并考虑重试。"
    fi
    sleep 2

    unmounted_nvme=()
    for d in "${NVME_DISKS[@]}"; do
      if has_any_mount_nvme "$d"; then
        : # 已挂载
      else
        unmounted_nvme+=("$d")
      fi
    done

    if ((${#unmounted_nvme[@]}==0)); then
      log "检测到所有 NVMe 目标磁盘已挂载成功。"
      break
    fi

    if (( attempt < max_mount_retries )); then
      log "仍未挂载的 NVMe 磁盘：${unmounted_nvme[*]}；3 秒后重试 ruko.sh 32..."
      sleep 3
    else
      die "重试 ${max_mount_retries} 次后 NVMe 仍未全部挂载成功，剩余未挂载：${unmounted_nvme[*]}"
    fi
  done
else
  log "未发现 NVMe 目标磁盘，跳过挂载重试与校验（忽略非 NVMe 设备）。"
fi
    # ========= 挂载重试（结束） =========

    # 生成新配置（已完成挂载）
    log "执行 acdn.sh 生成新配置"
    bash "$tmp_acdn"

    # 仅当 args.conf 存在 且 old_isp 非空 才恢复 ISP
    if [[ -f "$args_conf" && -n "${old_isp:-}" ]]; then
      if grep -qE -- '--isp=' "$args_conf"; then
        sed -i "s/--isp=.*/--isp=${old_isp}/" "$args_conf"
        log "已将 --isp 更新为: ${old_isp}"
      elif grep -qE -- '\<isp=' "$args_conf"; then
        sed -i "s/\\<isp=.*/isp=${old_isp}/" "$args_conf"
        log "已将 isp 更新为: ${old_isp}"
      else
        log "新配置中未找到 isp 字段，保持不变。"
      fi
    else
      log "跳过 ISP 恢复：args.conf 存在=$( [[ -f "$args_conf" ]] && echo yes || echo no )；old_isp='${old_isp:-}'"
    fi

    # 安装并启动
    bash "$tmp_install"
    sleep 2
    local kso_c
    kso_c="$(docker ps --format '{{.Names}}' | grep -m1 bbiz-kso-nexusplugin || true)"
    if [[ -n "$kso_c" ]]; then
      docker exec "$kso_c" bash /apps/gitrce/deploy/release/default/start.sh &>/dev/null || true
      log "容器内服务启动完成。"
    else
      log "未找到 bbiz-kso-nexusplugin 容器，略过启动脚本。"
    fi

    log "完成：discard_rate=$NEW_TCP，格式化→挂载(含重试)→配置→安装 流程已执行。"
    cat  /data/kuaicdn/bbiz/ksp2p/config/args.conf
  else
    log "当前值已达上限(=$max_tcp)，不做变更。"
  fi
}

# 执行
tune_tcp_and_redeploy
}